package org.xjc.config;

import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.xjc.config.securitycomponent.*;
import org.xjc.service.SecurityRoleService;

import javax.annotation.Resource;

/**
 * @Author : XJC
 * @Description :安全配置
 * @create : 2022/8/25 18:28
 * @Override public void configure(WebSecurity web) throws Exception {
 * web
 * .ignoring().antMatchers(
 * "/login",
 * "/register",
 * "/captcha",
 * "/admin/info",
 * "/ws/**"
 * );
 * }
 */
public abstract class AbstractSecurityConfig extends WebSecurityConfigurerAdapter {


    @Resource
    private SecurityRoleService roleService;

    @Resource
    private CustomSecurityMetadataSourceFilter customSecurityMetadataSourceFilter;

    @Resource
    private CustomUrlDecisionManager customUrlDecisionManager;

    @Resource
    private UserDetailsService userDetailsService;

    @Resource
    private PasswordEncoder bCryptPasswordEncoder;

    @Resource
    private JwtAuthenticationTokenFilter jwtAuthencationTokenFilter;

    /**
     * springsecurity会走自己配置的userdetailsservice
     *
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                //表单提交
                .csrf().disable()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .anyRequest()
                .authenticated()
                .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
                    @Override
                    public <O extends FilterSecurityInterceptor> O postProcess(O object) {
                        object.setAccessDecisionManager(customUrlDecisionManager);
                        object.setSecurityMetadataSource(customSecurityMetadataSourceFilter);
                        return object;
                    }
                })
                .and()
                .headers()
                .cacheControl();
        //添加jwt 登录授权过滤器
        http.addFilterBefore(jwtAuthencationTokenFilter,
                UsernamePasswordAuthenticationFilter.class);
        //添加自定义未授权和未登录结果返回
        http.exceptionHandling()
                .accessDeniedHandler(restfulAccessDeniedHandler())
                .authenticationEntryPoint(getEntryPoint());
    }



    public RestAuthorizationEntryPoint getEntryPoint() {
        return new RestAuthorizationEntryPoint();
    }

    public RestfulAccessDeniedHandler restfulAccessDeniedHandler() {
        return new RestfulAccessDeniedHandler();
    }


}